<?php
/**
 * 基础操作类
 * Created by PhpStorm.
 * User: zhangbing
 * Date: 2018/7/20
 * Time: 15:45
 */
namespace app\admin\controller;
use think\Controller;

class Base extends Controller{
    /**
     * @var 登录用户id
     */
    protected $id;

    /**
     * @var 请求参数
     */
    protected $params;

    /**
     * @var 请求路由
     */
    protected $route;

    /**
     * @var 日志
     */
    protected $logs;

    /**
     * @var 权限
     */
    protected $auth;

    /**
     * @var 用户信息
     */
    protected $info;

    /**
     * @var bool 登录验证，true开启，false关闭
     */
    protected $needLogin = true;

    /**
     * @var bool 权限验证，true开启，false关闭
     */
    protected $needAuth  = true;

    /**
     * @var bool 用户状态验证，true开启，false关闭
     */
    protected $needCheck = true;

    /**
     * 从一个难以访问的属性读取数据的时候(1.无访问权限2.未初始化) __get() 方法被调用
     * @param $name  属性名
     * @return mixed|\think\db\Query
     */
    public function __get($name){
        return $this->$name = \think\Db::name($name);
    }

    /**
     * 向一个难以访问的属性赋值的时候(1.无访问权限2.未初始化) __set() 方法被调用
     * @param $name 属性名
     * @param $value  属性值
     */
    public function __set($name, $value){
        $this->$name = $value;
    }

    protected function _initialize(){
        $this->id = \think\Session::get('login');  // 获取登录id
        $this->params = array_filter( input('param.') );  // 获取入参,并过滤空参数
        $this->route  = strtolower( '/'.$this->request->module().'/'.$this->request->controller().'/'.$this->request->action() );

        self::_constant();  // 常量定义
        self::_nav();  // 渲染面包屑导航
        self::_loginValid();  // 登录验证
        if ( $this->id == \Param::GROUP_ADMIN ) return true;  // 超管不做状态验证和权限验证
        self::_statusValid();  // 状态验证

        $this->auth = Auth::instance();
        $this->auth->_onoff = $this->needAuth;
        if ( $this->auth->check($this->route, $this->id) ) return true;
        if ( IS_POST ) return _error(-1, '抱歉，您不具备该权限!');  // ajax返回
        else $this->error('抱歉，您不具备该权限!');  // 跳转返回
        exit;
    }

    /**
     * 常量定义
     */
    private function _constant(){
        !defined('IS_POST') && define('IS_POST', $this->request->isPost()); // 定义是否POST请求
        !defined('IS_AJAX') && define('IS_AJAX', $this->request->isAjax()); // 定义是否AJAX请求
    }

    /**
     * 面包屑导航
     * @return mixed
     */
    private function _nav(){
        $nav = $this->joinOne(
            $this->auth_rule,
            [['auth_rule b','a.pid = b.id','inner']],
            ['a.auth_rule'=>$this->route],
            'a.rule_name son_rule,b.rule_name parent_rule,b.pid'
        );
        $this->assign(['nav'=>$nav,'route'=>$this->route]);
    }

    /**
     * 登陆验证
     */
    private function _loginValid(){
        if ( $this->needLogin ) {   // 登录验证
            if ( !$this->id ) $this->redirect('login/login');
            $session_end = \think\Session::get('session.end_time');  // 获取session结束时间
            if ($session_end < time()) {
                \think\Session::delete('login');
                $this->redirect('login/login');
            }
        }
    }

    /**
     * 用户状态验证
     * @return string|\think\response\Json
     * @throws \Exception
     */
    private function _statusValid(){
        if ( $this->needCheck) {   // 用户状态验证，通过则返回用户信息
            $this->info = $this->userInfo();
            if ( !$this->info ) {
                \think\Session::delete('login');
                if (IS_POST) return _error(-2, '抱歉，您已被禁用！');  // ajax返回
                else $this->error('抱歉，您已被禁用！');  // 跳转返回
                exit;
            }
        }
    }

    /**
     * 获取用户信息
     * @return mixed
     * @throws \Exception
     */
    protected function userInfo(){
        return $this->getRow($this->admin, ['id'=>$this->id,'status'=>\Param::STATUS_ON]);
    }

    /**
     * 返回多条记录
     * @param $obj object 对象模型
     * @param string $where
     * @param string $field
     * @param string $order
     * @param string $limit
     * @param string $group
     * @return mixed
     */
    protected function getList($obj, $where='',$field='*',$order='',$limit='',$group=''){
        return $obj->field($field)->where($where)->group($group)->order($order)->limit($limit)->select();
    }

    /**
     * 返回一条记录
     * @param $obj
     * @param $where
     * @param string $field
     * @return mixed
     */
    protected function getRow($obj, $where, $field='*'){
        return is_numeric($where) ? $obj->field($field)->find($where) : $obj->field($field)->where($where)->find();
    }

    /**
     * 聚合函数 统计
     * @param $obj
     * @param $where
     * @return mixed
     */
    protected function getCount($obj, $where){
        return $obj->where($where)->count();
    }

    /**
     * 返回某一列数据
     * @param $obj
     * @param $where
     * @param $field
     * @param string $order
     * @return mixed
     */
    protected function getColumn($obj, $where, $field, $order=''){
        return $obj->where($where)->order($order)->column($field);
    }

    /**
     * 连表查询单条信息
     * @param $obj
     * @param $join
     * @param $where
     * @param string $field
     * @return mixed
     */
    protected function joinOne($obj, $join, $where, $field='*'){
        return $obj->alias('a')->field($field)->join($join)->where($where)->find();
    }

    /**
     * 连表查询多条信息
     * @param $obj
     * @param $join
     * @param string $where
     * @param string $field
     * @param string $order
     * @param string $limit
     * @param string $group
     * @return mixed
     */
    public function joinMany($obj, $join, $where='',$field='*', $order='', $limit='', $group=''){
        return $obj->alias('a')->distinct(true)->field($field)->join($join)->where($where)->group($group)->order($order)->limit($limit)->select();
    }

    /**
     * 更新某个字段的值
     * @param $obj
     * @param $where
     * @param $field
     * @param string $value
     * @return mixed
     */
    protected function setValue($obj, $where, $field, $value){
        return $obj->where($where)->setField($field, $value);
    }

    /**
     * 返回某个字段的值
     * @param $obj
     * @param $where
     * @param $field
     * @return mixed
     */
    protected function getValue($obj, $where, $field){
        return $obj->where($where)->value($field);
    }
}